/*
 * funcionesMapeo.c
 *
 *  Created on: 10/11/2011
 *      Author: utn_so
 */
#include "planificador.h"


void Archivo_mapear(uint64_t **descriptorArchivo,char**map,struct stat **punteroEstructuraSTAT) {
	int32_t posmadvise;
	(*descriptorArchivo)= open(PATHARCHIVO,O_RDWR);
	if ((*descriptorArchivo) == -1) {
		perror("Error al abrir el archivo para escritura");
		exit(EXIT_FAILURE);
	}

	if (fstat ((*descriptorArchivo),*punteroEstructuraSTAT) < 0)
		perror ("fstat error");

	*map = mmap(0, (*punteroEstructuraSTAT)->st_size, PROT_READ | PROT_WRITE, MAP_SHARED, (*descriptorArchivo), 0);
	if (*map == MAP_FAILED) {
		close((*descriptorArchivo));
		perror("Error al mmappear el archivo");
		exit(EXIT_FAILURE);
	}
	posmadvise=posix_madvise(*map,(*punteroEstructuraSTAT)->st_size,MADV_SEQUENTIAL);

	if (posmadvise != 0) {
		perror("Error posix_madvise\n");
		//exit(EXIT_FAILURE);
	}
}



void Archivo_leer(int32_t numeroSector, char *infoAGrabar,char*map) {

	int32_t byteAEmpezar = sector_convertiteEnByte(numeroSector);
	memcpy(infoAGrabar,map + byteAEmpezar,512);
	infoAGrabar[512]='\0';

}
void Archivo_escribir(int32_t numeroSector, char infoAGrabar[512],char**map,struct stat **punteroEstructuraSTAT) {
	int32_t variablemsync;
	int32_t byteAEmpezar;
	cuantosSectoresEscribi++;
	byteAEmpezar = sector_convertiteEnByte(numeroSector);
	memcpy(*map + byteAEmpezar, infoAGrabar, 512);
	//memcpy(lecturaDeByte,*map,512);
	if (cuantosSectoresEscribi==sectoresTotalesDeDisco){
		variablemsync=msync(*map, (*punteroEstructuraSTAT)->st_size, MS_ASYNC);
		if (variablemsync != 0) {
			perror("Error msync\n");
			exit(EXIT_FAILURE);
		}
	}
}
int32_t sector_convertiteEnByte (int32_t sector) {
#define cantidadBytePorSector 512
	int32_t byte;
	return byte=sector*cantidadBytePorSector;
}
void Archivo_desmapear(uint64_t** descriptorArchivo, char **map, struct stat **punteroEstructuraSTAT) {
	/* Se libera la memoria mmappeada*/
	if (munmap(*map, (*punteroEstructuraSTAT)->st_size) == -1) {
		perror("Error al des-mapear el archivo");
	}
	/* desmapear no implica cierra el archivo, asi que lo cerramos*/
	close(*descriptorArchivo);
}

void lectura_atender(struct estructuraLeer **punteroLectura,char *map,char lecturaDeBytechar[513]){

	int32_t *trace = 0;
	int32_t *sincro = 0;
	int32_t numeroSector;
	int32_t descriptorAEnviar;

	numeroSector = algoritmoScanLectura_ejecutar(&(*punteroLectura),&sincro, &trace,&descriptorAEnviar);

	Archivo_leer(numeroSector,lecturaDeBytechar,map);

	/*for(i=0;i<512;i++){
	printf("%c\n",lecturaDeBytechar[i]);
	}*/
	//VER LOS TYPE DE ACA ABAJO

	if(sincro == 1){
		NIPC_enviar(socketGlobal,'4',SECTOR,lecturaDeBytechar,numeroSector);
	}
	else if(trace == 0){
		if(memcmp(stConfig.cModoInicio,"C",strlen("C"))==0){
			NIPC_enviar(socketGlobal,'3',SECTOR,lecturaDeBytechar,numeroSector);
		}else if(memcmp(stConfig.cModoInicio,"L",strlen("L"))==0){
			//descriptorElegido=fs_elegirAEnviar(numeroSector);
			NIPC_enviar(descriptorAEnviar,'3',SECTOR,lecturaDeBytechar,numeroSector);
			printf("Se envio al descriptor %d, el sector %d\n", descriptorAEnviar, numeroSector);
		}

	}
}

void escritura_atender(struct estructuraEscribir **punteroEscritura,char**map,struct stat **punteroEstructuraSTAT){

	int numeroSector;
	char infoSector[512];

	memset(infoSector,'\0',512);

	numeroSector = algoritmoScanEscritura_ejecutar(&(*punteroEscritura), &infoSector);
	if (numeroSector%500==0){
			printf("numeroSector: %d\n",numeroSector);
		}
	Archivo_escribir(numeroSector, infoSector, &(*map),&(*punteroEstructuraSTAT));
}






/*


int algoritmoScan_ejecutar(estructuraLeer** punteroFte, int** cambioDeSentido) {

	int siguienteALeer;
	int diferenciaEntreSectores=999999999;
	int traceActivo;
	estructuraLeer *auxiliar;
	auxiliar = *punteroFte;
 *cambioDeSentido = 0;
	if(direccionSCAN) {
		while(auxiliar) {
			if((posicionCabezal <= auxiliar->sectorPedido) && (auxiliar->sectorPedido - cantidadDePistas < diferenciaEntreSectores)) {
				diferenciaEntreSectores = auxiliar->sectorPedido-cantidadDePistas;
				siguienteALeer = auxiliar->sectorPedido;
				if(auxiliar->traceONoTrace == 1){
					traceActivo = 1;
				}

			}
			auxiliar = auxiliar->siguiente;
		}
		if(diferenciaEntreSectores == 999999999) {
			auxiliar = *punteroFte;
			direccionSCAN = 0;
 *cambioDeSentido = 1;
			siguienteALeer = auxiliar->sectorPedido;
			auxiliar = auxiliar->siguiente;
			while(auxiliar) {
				if(auxiliar->sectorPedido > siguienteALeer)
				     siguienteALeer = auxiliar->sectorPedido;
				auxiliar = auxiliar->siguiente;
			}
		}
	} else {
		while(auxiliar) {
			if((posicionCabezal >= auxiliar->sectorPedido) && (cantidadDePistas - auxiliar->sectorPedido < diferenciaEntreSectores)) {
				diferenciaEntreSectores = cantidadDePistas - auxiliar->sectorPedido;
				siguienteALeer = auxiliar->sectorPedido;
				if(auxiliar->traceONoTrace == 1){
						traceActivo = 1;
				}
			}
			auxiliar = auxiliar->siguiente;
		}
		if(diferenciaEntreSectores == 999999999) {
			auxiliar = *punteroFte;
			direccionSCAN = 1;
 *cambioDeSentido = 1;
			siguienteALeer = auxiliar->sectorPedido;
			auxiliar = auxiliar->siguiente;
			while(auxiliar) {
				if(auxiliar->sectorPedido < siguienteALeer)
				     siguienteALeer = auxiliar->sectorPedido;
				auxiliar = auxiliar->siguiente;
			}
		}
	}
	//ESTO HAY QUE VERLO BIEN EL ELIMINAR!!!!!!!!!!!!!!!!!!!!!!!
	if(traceActivo){
		realizarTrace(siguienteALeer,&cambioDeSentido);
	}
	eliminarNodo(punteroFte, siguienteALeer);
	return siguienteALeer;
}




void realizarTrace(int sectorABuscar, int cambioDeSentido){

	int pistasRecorridas;
	int sectoresRecorridos = 0;
	int i=0;
	char recorridoRealizado[200];

		sprintf(recorridoRealizado,"Posicion actual: %d:%d\n", posicionCabezal/punteroEstructuraConfiguracion->iSectoresPista,posicionCabezal % punteroEstructuraConfiguracion->iSectoresPista);
		sprintf(recorridoRealizado + strlen(recorridoRealizado), "Sector solicitado: %d:%d\n",sectorABuscar/punteroEstructuraConfiguracion->iSectoresPista,sectorABuscar % punteroEstructuraConfiguracion->iSectoresPista);

		if(sectorABuscar == posicionCabezal)
		{
			printf("Sector recorrido: %d:%d\n",sectorABuscar/punteroEstructuraConfiguracion->iSectoresPista,sectorABuscar % punteroEstructuraConfiguracion->iSectoresPista);
			printf("Tiempo consumido: %d ms\n",tiempoDeLectura);

			if((sectorABuscar % sectoresPorPista) == sectoresPorPista - 1)
				printf("Proximo sector: %d:0\n\n",sectorABuscar/sectoresPorPista);
			else
				printf("Proximo sector: %d:%d\n\n",sectorABuscar/sectoresPorPista,(sectorABuscar + 1) % sectoresPorPista );
		}
		else
		{
			sprintf(recorridoRealizado + strlen(recorridoRealizado),"Sectores Recorridos: ");
			if(posicionCabezal < sectorABuscar)
			{
				sprintf(recorridoRealizado + strlen(recorridoRealizado),"0:0 (pista inicial),");
				if(cambioDeSentido){
					pistasRecorridas = (posicionCabezal/sectoresPorPista) + (sectorABuscar/sectoresPorPista);
									//pistaActual + pistaDelSectorBuscado
				}else
					pistasRecorridas = (sectorABuscar/sectoresPorPista) - (posicionCabezal/sectoresPorPista);
									//pistaDelSectorBuscado - pistaActual
				if(direccionSCAN)
				{
					posicionCabezal = posicionCabezal + pistasRecorridas * sectoresPorPista;
				}
				else
				{
					posicionCabezal = posicionCabezal - pistasRecorridas * sectoresPorPista;
				}
			}
			else
			{

				if(cambioDeSentido){

					sprintf(recorridoRealizado + strlen(recorridoRealizado),"%d:%d (pista final), ",cantidadDePistas, sectoresPorPista-1);
					pistasRecorridas = (cantidadDePistas - (posicionCabezal/sectoresPorPista)) + (cantidadDePistas - (sectorABuscar/sectoresPorPista));
				}else
					pistasRecorridas = (posicionCabezal/sectoresPorPista) - (sectorABuscar/sectoresPorPista);

				posicionCabezal = posicionCabezal - ((posicionCabezal/sectoresPorPista) - (sectorABuscar/sectoresPorPista)) * sectoresPorPista;
			}

			sectoresRecorridos = 0;


			if(sectorABuscar % sectoresPorPista > posicionCabezal % sectoresPorPista)
			{

				while(sectorABuscar % sectoresPorPista != posicionCabezal % sectoresPorPista)
				{
				//	printf("%d:%d, ", posicionCabezal/sectoresPorPista, posicionCabezal % sectoresPorPista);
					sprintf(recorridoRealizado + strlen(recorridoRealizado),"%d:%d, ", posicionCabezal/sectoresPorPista, posicionCabezal % sectoresPorPista);
					posicionCabezal++;
					sectoresRecorridos++;
				}
			}
			else
			{
				while(posicionCabezal % sectoresPorPista != 0 && posicionCabezal != sectorABuscar)
				{
					sprintf(recorridoRealizado + strlen(recorridoRealizado),"%d:%d, ", posicionCabezal/sectoresPorPista, posicionCabezal % sectoresPorPista);
					posicionCabezal++;
					sectoresRecorridos++;
				}
				if(posicionCabezal % sectoresPorPista == 0)
				{
					posicionCabezal = posicionCabezal - sectoresPorPista;
					while(posicionCabezal != sectorABuscar)
					{
						sprintf(recorridoRealizado + strlen(recorridoRealizado),"%d:%d, ", posicionCabezal/sectoresPorPista, posicionCabezal % sectoresPorPista);
						posicionCabezal++;
						sectoresRecorridos++;
					}
				}
			}

			sprintf(recorridoRealizado + strlen(recorridoRealizado),"%d:%d\n",posicionCabezal/sectoresPorPista, posicionCabezal % sectoresPorPista);
			sprintf(recorridoRealizado + strlen(recorridoRealizado),"Tiempo consumido: %d ms\n", (pistasRecorridas * tiempoSaltoEntrePistas) + sectoresRecorridos * ((60000/RPM)/sectoresPorPista));

			if(posicionCabezal % sectoresPorPista == sectoresPorPista - 1)
				posicionCabezal = posicionCabezal - sectoresPorPista + 1;
			else
				posicionCabezal++;

			sprintf(recorridoRealizado + strlen(recorridoRealizado),"Próximo sector: %d:%d\n\n", posicionCabezal/sectoresPorPista,posicionCabezal % sectoresPorPista);

			printf("LLegue y este es el resultado: \n%s",recorridoRealizado);
		}
}






 */
